﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entidad;
using System.Data.SqlClient;
using System.Data;
//public enum Acciones { agregar, actualizar, eliminar};
namespace DAO
{

    public class VentaDAO
    {
        private DAO_v2 dao;
         public VentaDAO()
        {
            dao = new DAO_v2();
            
        }
        public string CadenaConexion()
        {
            return dao.StringConexion();
        }
        public DataView obtenerTipoFactura()
        {
            dao = new DAO_v2();
            SqlConnection cn = new SqlConnection();
            cn.ConnectionString = CadenaConexion();

            //List<Entidad.TipoFacturaEnt> resultado = new List<TipoFacturaEnt>();
            try
            {
                cn.Open();
                List<String> columnas = new List<String>();
                columnas.Add("id_TipoFactura");
                columnas.Add("nombre");
                SqlCommand cmd = new SqlCommand();
                cmd = (dao.CargarCombo("TipoFactura", columnas, "order by nombre"));
                cmd.Connection = cn;
               // SqlDataReader dr = cmd.ExecuteReader();
                DataTable dt = new DataTable();
                dt.Load(cmd.ExecuteReader());
                DataView resultado = new DataView(dt);
                return resultado;
            }
            catch (SqlException ex)
            {

                throw new ApplicationException("Problema al obtener los tipos de  facturas");
            }
            finally
            {

                dao.CerrarConexion(cn);
            }
      
        }


        public int? ObtenerNumeroUltima()
        {
            SqlConnection con = new SqlConnection(DAO_v2.MiCadenaConexion());
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = con;
                cmd.CommandType = System.Data.CommandType.Text;
                String comando = "SELECT TOP 1 numero ";
                comando += "FROM Factura  ";          
                comando += "ORDER BY numero DESC ";          
                cmd.CommandText = comando;
                int resultado;
                object res = cmd.ExecuteScalar();
                if (res != null)
                {
                    resultado = (int)res;
                }
                else
                {
                    resultado = 0;
                }
                return resultado;
            }
            catch (SqlException)
            {
                return null;
                throw new ApplicationException("Error al obtener el numero de la ultima factura");
            }
            finally
            {
                dao.CerrarConexion(con);
            }
        }

        public List<EjemplarBusquedaQueryEnt> ejemplaresGrilla(String filtro, Object dato)
        {
           


            dao = new DAO_v2();
            List<String> tablas = new List<String>();
            List<String> columnas = new List<String>();
            List<String> fk = new List<String>();
            List<String> pk = new List<String>();
            List<String> parametros = new List<String>() ;
            List<Object> datos = new List<Object>();
            tablas.Add("Ejemplar e");
            tablas.Add("Libro l");
            
            columnas.Add("e.id_Ejemplar as id_Ejemplar");
            columnas.Add("l.precioNuevo As PrecioNuevo");
            columnas.Add("l.titulo As Titulo");
            columnas.Add("e.codigo As Codigo");
            columnas.Add("e.codigo As Codigo");
            fk.Add("e.id_Libro");
            pk.Add("l.id_Libro");
            parametros.Add(filtro);
            datos.Add(dato);

            SqlConnection con = new SqlConnection(CadenaConexion());

            List<EjemplarBusquedaQueryEnt> resultado;
            try
            {
                con.Open();
                SqlCommand cmd = dao.BuscarVariasTablasConFiltro(tablas, columnas, fk, pk, parametros, datos);
                cmd.Connection = con;
                SqlDataReader dr = cmd.ExecuteReader();
                resultado = new List<EjemplarBusquedaQueryEnt>();
                while (dr.Read())
                {
                    EjemplarBusquedaQueryEnt ejemplar = new EjemplarBusquedaQueryEnt();
                 
                    ejemplar.Id_Ejemplar = int.Parse(dr["id_Ejemplar"].ToString());
 
                    ejemplar.Titulo = dr["Titulo"].ToString();
                    ejemplar.Precio = double.Parse(dr["PrecioNuevo"].ToString());
                   // ejemplar.Disponibilidad = bool.Parse(dr["Disponible"].ToString());
  
                    ejemplar.Codigo = int.Parse(dr["Codigo"].ToString());
                    resultado.Add(ejemplar);
                }
                dr.Close();
                return resultado;
            }
            catch (SqlException ex)
            {
                return null;
                throw new ApplicationException("Error al buscar ejemplares..");
            }
            finally
            {
                dao.CerrarConexion(con);
            }


        }

        public List<EjemplarBusquedaQueryEnt> ejemplaresGrilla()
        {



            dao = new DAO_v2();
            List<String> tablas = new List<String>();
            List<String> columnas = new List<String>();
            List<String> fk = new List<String>();
            List<String> pk = new List<String>();
            List<String> parametros = new List<String>();
            List<Object> datos = new List<Object>();
            tablas.Add("Ejemplar e");
            tablas.Add("Libro l");

            columnas.Add("e.id_Ejemplar as id_Ejemplar");
            columnas.Add("l.precioNuevo As PrecioNuevo");
            columnas.Add("l.titulo As Titulo");
            columnas.Add("e.codigo As Codigo");
            // columnas.Add("e.disponibilidad As Disponible");
            columnas.Add("e.codigo As Codigo");
            fk.Add("e.id_Libro");
            pk.Add("l.id_Libro");


            SqlConnection con = new SqlConnection(CadenaConexion());

            List<EjemplarBusquedaQueryEnt> resultado;
            try
            {
                con.Open();
                SqlCommand cmd = dao.BuscarVariasTablasSinFiltro(tablas, columnas, fk, pk);
                cmd.Connection = con;
                SqlDataReader dr = cmd.ExecuteReader();
                resultado = new List<EjemplarBusquedaQueryEnt>();
                while (dr.Read())
                {
                    EjemplarBusquedaQueryEnt ejemplar = new EjemplarBusquedaQueryEnt();

                    ejemplar.Id_Ejemplar = int.Parse(dr["id_Ejemplar"].ToString());

                    ejemplar.Titulo = dr["Titulo"].ToString();
                    ejemplar.Precio = double.Parse(dr["PrecioNuevo"].ToString());
                    ejemplar.Codigo = int.Parse(dr["Codigo"].ToString());
                    resultado.Add(ejemplar);
                }
                dr.Close();
                return resultado;
            }
            catch (SqlException ex)
            {
                return null;
                throw new ApplicationException("Error al buscar ejemplares..");
            }
            finally
            {
                dao.CerrarConexion(con);
            }


        }
        public FacturaEnt ObtenerFactura(int numero)
        {
            SqlConnection con = new SqlConnection(CadenaConexion());
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand();
                List<String> columnas = new List<String>();
                List<String> parametros = new List<String>();
                List<Object> datos = new List<Object>();
                columnas.Add("id_Factura");
                columnas.Add("id_TipoFactura");
                columnas.Add("id_Usuario");
                columnas.Add("numero");
                columnas.Add("fecha");
                columnas.Add("total");
                parametros.Add("numero");
                datos.Add(numero);
                cmd = dao.Buscar("Factura", columnas, parametros, datos);
                cmd.Connection = con;
                SqlDataReader dr = cmd.ExecuteReader();
                FacturaEnt resultado = new FacturaEnt();
               while(dr.Read()){
                resultado.id_Factura = int.Parse(dr["id_Factura"].ToString());
                resultado.TipoFacturaID = int.Parse(dr["id_TipoFactura"].ToString());
                resultado.UsuarioID = int.Parse(dr["id_Usuario"].ToString());
                resultado.Numero = int.Parse(dr["numero"].ToString());
                resultado.Total = decimal.Parse(dr["total"].ToString());
                resultado.Fecha = DateTime.Parse(dr["fecha"].ToString());
               }
                return resultado; 

            }
            catch (SqlException ex)
            {
                return null;
                throw new ApplicationException("Error al obtener la factura");
            }
            finally
            {
                dao.CerrarConexion(con);

            }

        }

        public bool GuardarFactura(FacturaEnt factura, List<DetalleFacturaEnt> detalles)
        {
            SqlConnection con = new SqlConnection(CadenaConexion());
            try
            {
                con.Open();
                SqlTransaction tran = con.BeginTransaction();
                SqlCommand cmd = new SqlCommand();
                
               
                DetalleFacturaDAO detalleDAO = new DetalleFacturaDAO();

                //Grabo Factura
                List<String> parametros = new List<String>();
                List<Object> datos = new List<Object>();
                parametros.Add("id_TipoFactura");
                datos.Add(factura.TipoFacturaID);
                parametros.Add("id_Usuario");
                datos.Add(factura.UsuarioID);
                parametros.Add("numero");
                datos.Add(factura.Numero);
                parametros.Add("fecha");
                datos.Add(factura.Fecha);
                parametros.Add("total");
                datos.Add(factura.Total);
                parametros.Add("anulada");
                datos.Add(false);
  
                cmd = dao.Grabar("Factura", parametros, datos);
                cmd.Connection = con;
                cmd.Transaction = tran;
                int id_Factura = Convert.ToInt32(cmd.ExecuteScalar());
               

                //Grabo los detalles 
                foreach (DetalleFacturaEnt detalle in detalles)
                {
                    detalleDAO.GuardarDetalle(detalle, tran, id_Factura, factura.UsuarioID, con);
                    // ID USUARIO Se lo paso desde la factura... Me parece que este id no iria en detalle...
                }

                tran.Commit();
                return true;

                }
            catch (SqlException ex)
            {
               
                return false;
                
                throw new ApplicationException ("Error al guardar factura");
            }
            finally
            {
                dao.CerrarConexion(con);

            }


        }
        public bool anularFactura(FacturaEnt factura,List<DetalleFacturaEnt>  detalles )
        {
            SqlConnection con = new SqlConnection(CadenaConexion());
            DetalleFacturaDAO detalleDAO = new DetalleFacturaDAO();
            try
            {
                List<String> parametros = new List<String>();
                List<Object> datos = new List<Object>();
                con.Open();
                SqlTransaction tran = con.BeginTransaction();
                SqlCommand cmd = new SqlCommand();
                String comando = "UPDATE Factura SET anulada = @anulada WHERE numero = @numero ";
                cmd.Parameters.AddWithValue("@anulada", true);
                cmd.Parameters.AddWithValue("@numero", factura.Numero);
                cmd.CommandText = comando;
                cmd.Connection = con;
                cmd.Transaction = tran;
                cmd.ExecuteNonQuery();
                foreach (DetalleFacturaEnt det in detalles)
                {
                    detalleDAO.EliminarDetalle(det, tran, con);
                }
                tran.Commit();
                 return true;
            }
            catch (SqlException)
            {
                 return false;
                 
                throw new ApplicationException("Error al actualizar la restauracion");
            }
            finally
            {
                if (con.State == System.Data.ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }
        public bool ActualizarFactura(FacturaEnt factura, List<DetalleFacturaEnt> agregar, List<DetalleFacturaEnt> eliminar, List<DetalleFacturaEnt> actualizar)
        {
            SqlConnection con = new SqlConnection(CadenaConexion());
            DetalleFacturaDAO detalleDAO = new DetalleFacturaDAO();
            try
            {
                List<String> parametrosSet = new List<String>();
                List<Object> datosSet = new List<Object>();
                List<String> parametrosWhere = new List<String>();
                List<Object> datosWhere = new List<Object>();
                con.Open();
                SqlTransaction tran = con.BeginTransaction();
                SqlCommand cmd = new SqlCommand();
                parametrosSet.Add("id_TipoFactura");
                datosSet.Add(factura.TipoFacturaID);
                parametrosSet.Add("id_Usuario");
                datosSet.Add(factura.UsuarioID);
                parametrosSet.Add("fecha");
                datosSet.Add(factura.Fecha);
                parametrosSet.Add("total");
                datosSet.Add(factura.Total);

                parametrosWhere.Add("numero");
                datosWhere.Add(factura.Numero);

                cmd = dao.Actualizar("Factura", parametrosSet, datosSet, parametrosWhere, datosWhere);
                cmd.Connection = con;
                cmd.Transaction = tran;
                cmd.ExecuteNonQuery();

                foreach (DetalleFacturaEnt dAgregar in agregar)
                {
                    detalleDAO.GuardarDetalle(dAgregar, tran, factura.id_Factura.Value, factura.UsuarioID, con);
                  
                }
                foreach (DetalleFacturaEnt dEliminar in eliminar)
                {
                    detalleDAO.EliminarDetalle(dEliminar, tran, con);
                }
                foreach (DetalleFacturaEnt dActualizar in actualizar)
                {
                    detalleDAO.ActualizarDetalle(dActualizar,tran, factura.id_Factura.Value, factura.UsuarioID, con);
                }
                tran.Commit();
                return true;
            }
            catch (SqlException)
            {
                return false;
                throw new ApplicationException("Error al actualizar la restauracion");
            }
            finally
            {
                if (con.State == System.Data.ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }

    }
}
